global g_root "C:\Users\Hongye Guo\Dropbox (Personal)\Density\Code\Production\Submission"

use "$g_root\Data\stacked_qtr_202106.dta", clear

* Basic processing
{
	* Date conversion
	gen test = date(fpedats, "DMY", 1990)
	drop fpedats 
	rename test fpedats 
	duplicates drop 

	* Actuals
	merge m:1 permno fpedats using "$g_root\Data\IBES_actuals.dta", keep(1 3) nogen
	rename forecast_month ym 

	* Generate stock-fp-month level of revisions and surprises 
	sort permno fpedats ym
	by permno fpedats: gen med_value_usd_chg = med_value_usd - med_value_usd[_n-1]
	by permno fpedats: gen sup_usd = actual_usd - med_value_usd[_n-1]

	merge m:1 permno ym using "$g_root/Data\crsp_prc_shrout.dta", keep(1 3) nogen
	drop if mi(mkval_l1m) | mi(prc_adj_l1m)

	gen yq = qofd(dofm(ym))
}

* Scale the surprises by adjusted stock prices, as is standard in the literature
{
	sort yq
	gen rev_final = med_value_usd_chg/prc_adj_l1m
	by yq: egen p_up = pctile(rev_final), p(99)
	by yq: egen p_down = pctile(rev_final), p(1)
	replace rev_final = p_up if !mi(rev_final) & rev_final>p_up
	replace rev_final = p_down if !mi(rev_final) & rev_final<p_down
	drop p_up p_down
	
	gen sup_final = sup_usd/prc_adj_l1m
	by yq: egen p_up = pctile(sup_final), p(99)
	by yq: egen p_down = pctile(sup_final), p(1)
	gen up_win_flag = !mi(sup_final) & sup_final>p_up
	gen low_win_flag = !mi(sup_final) & sup_final<p_down
	replace sup_final = p_up if !mi(sup_final) & sup_final>p_up
	replace sup_final = p_down if !mi(sup_final) & sup_final<p_down
	replace sup_final = . if ym != mofd(anndats_act)
	drop p_up p_down
}

* Table 8
{
	* Decompose the term structure of the revisions and surprises
	gen ym_anndats = mofd(anndats_act)
	gen month_dis = ym_anndats - ym
	gen yq_anndats = qofd(anndats_act)
	assert yq == qofd(dofm(ym))
	gen quarter_dis = yq_anndats - yq
	tab quarter_dis if quarter_dis<4 & !mi(rev_final)
	drop if month_dis > 13 | month_dis < 0 

	sort ym quarter_dis
	by ym quarter_dis: egen temp_den = total(mkval_l1m)
	gen reg_wgt = mkval_l1m/temp_den
	drop temp_den

	* Very occasionally there are cases where multiple earnings got announced in the same quarter
	* these are less than 0.5% of the data. So they do not matter
	*duplicates tag permno ym month_dis, gen(dtag)
	*tab dtag
	*drop dtag

	sort permno fpedats ym
	gen double permno_fp = permno*10000 + fpedats 

	tsset permno_fp ym
	forvalues i = 1/13{
		gen rev_final_l`i'm = L`i'.rev_final
	}

	gen month = month(dofm(ym))
	gen am_flag = mod(month, 3)==1
	
	gen rev_final_lt12m = rev_final_l1m
	forvalues i = 2/12{
		replace rev_final_lt12m = rev_final_lt12m + rev_final_l`i'm 
	}
	
	* Truncate the early part of the sample where the cross sections are too thin
	* This is determined by the cs surprise max-min distance being too close
	* It makes little difference is this is not done at all
	* But it is conceptually good to do
	/*
	sort ym
	by ym: gen ym_flag = _n==1
	by ym: egen ym_max_sup_final = max(sup_final)
	by ym: egen ym_min_sup_final = min(sup_final)
	format ym %tm
	order ym ym_max_sup_final ym_min_sup_final
	tw line ym_max_sup_final ym if ym_flag || line ym_min_sup_final ym if ym_flag
	br if ym_flag
	*/
	drop if ym<ym(1984,5)
	
	forvalues i = 1/4{
		local j = (`i'-1)*3 
		local jp1 = `j' + 1
		local jp2 = `j' + 2
		local jp3 = `j' + 3
		foreach l_var in rev_final {
			gen `l_var'_prevq1_l`i'q = `l_var'_l`jp1'm
			replace `l_var'_prevq1_l`i'q = `l_var'_l`jp2'm if mod(month,3)==0
			replace `l_var'_prevq1_l`i'q = `l_var'_l`jp3'm if mod(month,3)==1
		}
	}
	gen rev_final_prevq1_t4q = rev_final_prevq1_l1q + rev_final_prevq1_l2q + rev_final_prevq1_l3q + rev_final_prevq1_l4q 

	forvalues i = 1/4{
		local j = (`i'-1)*3 
		local jp1 = `j' + 1
		local jp2 = `j' + 2
		local jp3 = `j' + 3
		foreach l_var in rev_final {
			gen `l_var'_prevq1_nm_l`i'q = `l_var'_l`jp2'm + `l_var'_l`jp3'm if mod(month,3)==2
			replace `l_var'_prevq1_nm_l`i'q = `l_var'_l`jp1'm + `l_var'_l`jp3'm if mod(month,3)==0
			replace `l_var'_prevq1_nm_l`i'q = `l_var'_l`jp1'm + `l_var'_l`jp2'm if mod(month,3)==1
		}
	}
	gen rev_final_prevq1_nm_t4q = rev_final_prevq1_nm_l1q + rev_final_prevq1_nm_l2q + rev_final_prevq1_nm_l3q + rev_final_prevq1_nm_l4q 

	sort yq 
	by yq: egen yq_mkval = total(mkval)
	gen int_term = am_flag * rev_final_lt12m 
	
	* Table 8
	clear matrix
	local col_count = 0
	
	reg sup_final rev_final_lt12m am_flag int_term [aw = reg_wgt], cluster(yq)
	local col_count = `col_count' + 1
	estimates store exp_`col_count'	
	
	gen int_2 = rev_final_prevq1_t4q * am_flag

	reg sup_final rev_final_prevq1_t4q am_flag int_2 [aw = reg_wgt], cluster(yq)
	local col_count = `col_count' + 1
	estimates store exp_`col_count'	
	
	gen int_3 = rev_final_prevq1_nm_t4q * am_flag
	
	reg sup_final rev_final_prevq1_nm_t4q am_flag int_3 [aw = reg_wgt], cluster(yq)
	local col_count = `col_count' + 1
	estimates store exp_`col_count'	
	
	local l_date : display %tdCYND date(c(current_date), "DMY")
	local l_time = substr(c(current_time), 1, 2) + substr(c(current_time), 4, 2)
	esttab exp_* using "$g_root/Output/CS_imp_nimp_`l_date'`l_time'.csv", star(* 0.1  ** 0.05 *** 0.01) b(3) t(2) r2 br noomit replace 
	
}


